/**
 * 性能优化工具函数
 */

// 组件预加载管理器
class ComponentPreloader {
  private preloadedComponents = new Set<string>()
  private loadingQueue = new Map<string, Promise<any>>()
  private componentCache = new Map<string, any>()

  /**
   * 预加载组件
   */
  async preloadComponent(type: string): Promise<void> {
    if (this.preloadedComponents.has(type)) {
      return
    }

    if (this.loadingQueue.has(type)) {
      await this.loadingQueue.get(type)
      return
    }

    const loadPromise = this.loadComponent(type)
    this.loadingQueue.set(type, loadPromise)

    try {
      await loadPromise
      this.preloadedComponents.add(type)
    } finally {
      this.loadingQueue.delete(type)
    }
  }

  /**
   * 加载组件
   */
  private async loadComponent(type: string): Promise<any> {
    if (this.componentCache.has(type)) {
      return this.componentCache.get(type)
    }

    let component
    switch (type) {
      case 'text':
        component = await import('@/components/widgets/TextWidget.vue')
        break
      case 'button':
        component = await import('@/components/widgets/ButtonWidget.vue')
        break
      case 'image':
        component = await import('@/components/widgets/ImageWidget.vue')
        break
      case 'container':
        component = await import('@/components/widgets/ContainerWidget.vue')
        break
      default:
        throw new Error(`Unknown component type: ${type}`)
    }

    this.componentCache.set(type, component.default || component)
    return this.componentCache.get(type)
  }

  /**
   * 批量预加载组件
   */
  async preloadComponents(types: string[]): Promise<void> {
    const promises = types.map(type => this.preloadComponent(type))
    await Promise.all(promises)
  }

  /**
   * 获取已预加载的组件
   */
  getPreloadedComponent(type: string): any {
    return this.componentCache.get(type)
  }

  /**
   * 清理缓存
   */
  clearCache(): void {
    this.componentCache.clear()
    this.preloadedComponents.clear()
  }
}

// 全局预加载器实例
export const componentPreloader = new ComponentPreloader()

// 性能监控器
export class PerformanceMonitor {
  private metrics = new Map<string, number[]>()
  private startTimes = new Map<string, number>()

  /**
   * 开始计时
   */
  startTimer(name: string): void {
    this.startTimes.set(name, performance.now())
  }

  /**
   * 结束计时
   */
  endTimer(name: string): number {
    const startTime = this.startTimes.get(name)
    if (!startTime) {
      return 0
    }

    const duration = performance.now() - startTime
    if (!this.metrics.has(name)) {
      this.metrics.set(name, [])
    }
    this.metrics.get(name)!.push(duration)

    this.startTimes.delete(name)
    return duration
  }

  /**
   * 获取性能指标
   */
  getMetrics(name: string): { avg: number; min: number; max: number; count: number } {
    const values = this.metrics.get(name) || []
    if (values.length === 0) {
      return { avg: 0, min: 0, max: 0, count: 0 }
    }

    const sum = values.reduce((a, b) => a + b, 0)
    const avg = sum / values.length
    const min = Math.min(...values)
    const max = Math.max(...values)

    return { avg, min, max, count: values.length }
  }

  /**
   * 清理指标
   */
  clearMetrics(): void {
    this.metrics.clear()
    this.startTimes.clear()
  }
}

// 全局性能监控器实例
export const performanceMonitor = new PerformanceMonitor()

// 组件使用频率统计
export class ComponentUsageTracker {
  private usageCount = new Map<string, number>()
  private lastUsed = new Map<string, number>()

  /**
   * 记录组件使用
   */
  trackUsage(type: string): void {
    const count = this.usageCount.get(type) || 0
    this.usageCount.set(type, count + 1)
    this.lastUsed.set(type, Date.now())
  }

  /**
   * 获取组件使用统计
   */
  getUsageStats(type: string): { count: number; lastUsed: number } {
    return {
      count: this.usageCount.get(type) || 0,
      lastUsed: this.lastUsed.get(type) || 0
    }
  }

  /**
   * 获取最常用的组件
   */
  getMostUsedComponents(limit: number = 10): Array<{ type: string; count: number }> {
    return Array.from(this.usageCount.entries())
      .sort(([, a], [, b]) => b - a)
      .slice(0, limit)
      .map(([type, count]) => ({ type, count }))
  }

  /**
   * 清理统计数据
   */
  clearStats(): void {
    this.usageCount.clear()
    this.lastUsed.clear()
  }
}

// 全局组件使用统计器实例
export const componentUsageTracker = new ComponentUsageTracker()

// 智能预加载策略
export class SmartPreloader {
  /**
   * 根据使用频率智能预加载
   */
  static async smartPreload(): Promise<void> {
    const mostUsed = componentUsageTracker.getMostUsedComponents(5)
    const typesToPreload = mostUsed.map(item => item.type)
    
    if (typesToPreload.length > 0) {
      await componentPreloader.preloadComponents(typesToPreload)
    }
  }

  /**
   * 预加载基础组件
   */
  static async preloadBasicComponents(): Promise<void> {
    const basicTypes = ['text', 'button']
    await componentPreloader.preloadComponents(basicTypes)
  }

  /**
   * 预加载媒体组件
   */
  static async preloadMediaComponents(): Promise<void> {
    const mediaTypes = ['image']
    await componentPreloader.preloadComponents(mediaTypes)
  }
}

// 导出工具函数
export const performanceUtils = {
  // 防抖函数
  debounce<T extends (...args: any[]) => any>(
    func: T,
    wait: number
  ): (...args: Parameters<T>) => void {
    let timeout: ReturnType<typeof setTimeout>
    return (...args: Parameters<T>) => {
      clearTimeout(timeout)
      timeout = setTimeout(() => func(...args), wait)
    }
  },

  // 节流函数
  throttle<T extends (...args: any[]) => any>(
    func: T,
    limit: number
  ): (...args: Parameters<T>) => void {
    let inThrottle: boolean
    return (...args: Parameters<T>) => {
      if (!inThrottle) {
        func(...args)
        inThrottle = true
        setTimeout(() => inThrottle = false, limit)
      }
    }
  },

  // 异步队列处理
  async processQueue<T>(
    items: T[],
    processor: (item: T) => Promise<void>,
    concurrency: number = 3
  ): Promise<void> {
    const queue = [...items]
    const running = new Set<Promise<void>>()

    while (queue.length > 0 || running.size > 0) {
      while (running.size < concurrency && queue.length > 0) {
        const item = queue.shift()!
        const promise = processor(item).finally(() => {
          running.delete(promise)
        })
        running.add(promise)
      }

      if (running.size > 0) {
        await Promise.race(running)
      }
    }
  }
} 